// OCyEntropiaSSPDlg.h : header file
//

#pragma once
#include "afxcmn.h"
#include "afxwin.h"
#include <vector>

// COCyEntropiaSSPDlg dialog
class COCyEntropiaSSPDlg : public CDialog
{
// Construction
public:
	COCyEntropiaSSPDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	enum { IDD = IDD_OCYENTROPIASSP_DIALOG };

// Implementation
protected:
	virtual void 
		DoDataExchange(CDataExchange* pDX);	// DDX/DDV support

	// Generated message map functions
	virtual BOOL 
		OnInitDialog();
	afx_msg void 
		OnPaint();
	afx_msg HCURSOR 
		OnQueryDragIcon();
	afx_msg void 
		OnNMDblclkMultisetsResults(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void 
		OnBnClickedBtRuntest();
	afx_msg void 
		OnEnChangeEdValFirstElem();
	afx_msg void 
		OnEnChangeEdN();

protected:
	void	
		InitializePrecalculatedValues(void);
	// Calcula el termino i-esimo de la secuencia de Kcci (0 0 0 ... 1) Kcci(k) = 1
	long	
		Kcci	(const int k, const int i);
	// Sumatoria de los primeros i naturales
	long	
		Gauss	(int i);
	void	
		ComputeMultiSetWithOneCompliance	(const int n, const int k, std::vector<long> &multiset);
	bool 
		HasComprehensiveIntraPartitionOrder(int n, std::vector<long> &set, int &howManyOK);

	bool 
		HasInterPartitionOrder( int n, std::vector<long> &set, int &howManyOK );

	long 
		ComputeTerm2( const int n, const int k, const int j);

	// Termino base usado en la recursion y definido de manera que S(1) sea 1
	long	
		A	(int n, int k, int valFirstElem );
	void 
		ShowMultiset (CListCtrl &lstCtrl, int fstCol, int n, int k, const std::vector<long> &set);

protected:
	// Esta lista contiene Los Multisets generados e informa en su primer columna 
	// si cumplen la propiedad
	HICON 
		m_hIcon;
	CListCtrl			
		m_lsMultisetsResults;
	CListCtrl			
		m_lsKcci;
	CComboBox			
		m_cboGauss;
	static bool			
		s_initialized;
	static std::vector<std::vector<long> >	
		m_precalculatedKccis;
	CSpinButtonCtrl		
		m_spinN;
	CEdit				
		m_edN;
	std::vector<std::vector<long> *>
		m_multisetResults;

	// Aqui se setea el valor del primer elemento del conjunto.
	CSpinButtonCtrl m_spValFirstElem;
	// Same as spin
	CEdit m_edValFirstElem;

	DECLARE_MESSAGE_MAP()
};
